package cms.common.data;


import cms.common.exception.ServiceException;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.function.Supplier;

@Slf4j
@ToString
public class ApiResult<T> {

    protected int code;
    protected String message;
    protected T data;
    protected ResultCode resultCode;

    public ApiResult() {
    }

    public ApiResult(ResultCode resultCode){
        this.resultCode = resultCode;
        this.code = resultCode.getCode();
        this.message = resultCode.getMessage();
    }

    public static <T> ApiResult<T> buildSuccess() {
        ApiResult<T> response = new ApiResult(ApiResultCode.SUCCESS);
        return response;
    }
    public static <T> ApiResult<T> buildSuccess(ResultCode resultCode) {
        ApiResult<T> response = new ApiResult(resultCode);
        return response;
    }

    /**
     * 忽略哪
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ApiResult<T> buildSuccess(T data) {
        ApiResult<T> response = new ApiResult(ApiResultCode.SUCCESS);
        response.data = data;
        return response;
    }

    /**
     * 带异常判断的返回,配合校验
     *
     * @param resultCode
     * @param e
     * @param <T>
     * @return
     */
    public static <T> ApiResult<T> buildFailure(ResultCode resultCode, Throwable e) {
        if(e instanceof  IllegalArgumentException){//处理Assert出的异常
            return ApiResult.buildFailure(ApiResultCode.PARAM_ERROR.setMessage(e.getMessage()));
        } else if(e instanceof ServiceException){
            ServiceException ee = (ServiceException)e;
            return ApiResult.buildFailure(ee.getCode(),ee.getMessage()).setData(ee.joinDetail());
        }else{
            ApiResult<T> response = new ApiResult(resultCode);
            return response;
        }
    }

    public static <T> ApiResult<T> buildFailure(ResultCode resultCode) {
        ApiResult<T> response = new ApiResult(resultCode);
        return response;
    }

    /**
     * 支持函数式编程，用于UT测试
     * @param supplier
     * @param <R>
     * @return
     */
    public static <R> R  buildApiResonse(Supplier<R> supplier) {
        return supplier.get();
    }

    public static <T> ApiResult<T> buildFailure(int errorCode, String errorMsg) {
        ApiResult<T> response = new ApiResult();
        response.code = errorCode;
        response.message = errorMsg;
        return response;
    }


    public int getCode() {
        return this.code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return StringUtils.defaultIfBlank( getDictMassage(),this.message);
    }

    /**
     * 解析国际化提示
     * @return
     */
    private String getDictMassage(){
//        DictEntry dictEntry = DictUtils.getDictEntry("API_RESULT_CODE",""+this.code);
//        if(null != dictEntry){
//            return dictEntry.getDictName();
//        }
        return null;
    }

    public ApiResult<T> setMessage(String message) {
        this.message = message;
        return this;
    }

    public T getData() {
        return this.data;
    }

    public ApiResult setData(T data) {
        this.data = data;
        return this;
    }


    /**
     * success
     * @return
     */
    public boolean isSuccess() {
        return code==ApiResultCode.SUCCESS.getCode() || resultCode==ApiResultCode.SUCCESS;
    }
}
